package com.code.telegram.services.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.code.telegram.exceptions.WalletException;
import com.code.telegram.managers.HttpManager;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 请求钱包服务
 *
 * @author xiaoyaowang
 */
@Service
public class RequestWalletService {

    private static Logger log = LoggerFactory.getLogger(RequestWalletService.class);

    @Resource
    @Lazy
    private HttpManager httpManager;

    @Value("${wallet.transfer.accountName}")
    private String accountName;

    @Value("${wallet.transfer.secondAmount}")
    private String secondAmount;

    @Value("${wallet.transfer.thirdAmount}")
    private Integer thirdAmount;

    @Value("${wallet.transfer.tpErc20Addr}")
    private String tpErc20Addr;

    @Value("${wallet.transfer.memo}")
    private String memo;

    @Value("${wallet.transfer.precision}")
    private Integer precision;

    /**
     * 打开钱包
     *
     * @return 打开钱包与否
     */
    public Boolean openWallet() {
        List<Object> params = new ArrayList<>();
        // 下面固定死
        params.add("tp-airdrop1023.");
        String body = httpManager.sendRpcReq("unlock", params);
        if (StringUtils.isNotBlank(body)) {
            JSONObject resultJson = JSON.parseObject(body);
            if (resultJson.containsKey("error")) {
                JSONObject errorJson = resultJson.getJSONObject("error");
                if (null != errorJson) {
                    log.error("请求钱包异常返回数据:{}", errorJson);
                    throw new WalletException(errorJson.toJSONString());
                }
            }
        } else {
            return false;
        }
        return true;
    }

    /**
     * 向审核通过的地址转账
     *
     * @return 打开钱包与否
     */
    public Boolean transferToAddr(String walletAddr, String amount) {
        List<Object> params = new ArrayList<>();
        // 下面固定死
        params.add(accountName);
        params.add(new BigDecimal(secondAmount).setScale(precision, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
        params.add(thirdAmount);
        params.add(tpErc20Addr);
        params.add("transfer");
        StringBuilder sb = new StringBuilder(1 << 3);
        sb.append(walletAddr);
        sb.append(",");
        sb.append(new BigDecimal(amount).multiply(new BigDecimal("100000000")).setScale(precision, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
        sb.append(",");
        sb.append(memo);
        params.add(sb.toString());
        String body = httpManager.sendRpcReq("invoke_contract", params);
        if (!StringUtils.isBlank(body)) {
            JSONObject resultJson = JSON.parseObject(body);
            if (resultJson.containsKey("error")) {
                JSONObject errorJson = resultJson.getJSONObject("error");
                if (null != errorJson) {
                    log.error("请求钱包异常返回数据:{}", errorJson);
                    throw new WalletException(errorJson.toJSONString());
                }
            }
        } else {
            return false;
        }
        return true;
    }

    /**
     * 关闭钱包
     *
     * @return 关闭钱包与否
     */
    public Boolean closeWallet() {
        List<Object> params = new ArrayList<>();
        // 下面固定死
        String body = httpManager.sendRpcReq("lock", params);
        if (!StringUtils.isBlank(body)) {
            JSONObject resultJson = JSON.parseObject(body);
            if (resultJson.containsKey("error")) {
                JSONObject errorJson = resultJson.getJSONObject("error");
                if (null != errorJson) {
                    log.error("请求钱包异常返回数据:{}", errorJson);
                    throw new WalletException(errorJson.toJSONString());
                }
            }
        } else {
            return false;
        }
        return true;
    }

    /**
     * 转账
     *
     * @param walletAddr 钱包地址
     * @param amount     金额
     */
    public void transferAmountToAddr(String walletAddr, String amount) {
        // 第一步：打开钱包
        boolean openWallet = openWallet();
        // 第二步：向审核成功的地址转账
        boolean transfer = false;
        if (openWallet) {
            transfer = transferToAddr(walletAddr, amount);
        }
        // 第三步：关闭钱包
        if (transfer) {
            closeWallet();
        }
    }

}
